package cc.rengu.igas.route.core.service.trans;

import cc.rengu.igas.route.common.constant.SmartRouteParamConstant;
import cc.rengu.igas.route.common.dao.NonFinanceTxnRouteCustomMapper;
import cc.rengu.igas.route.common.dao.impl.NonFinanceTxnRouteCustomMapperImpl;
import cc.rengu.igas.route.common.enums.RouteTxnNumEnum;
import cc.rengu.igas.route.common.enums.SmartRouteRspEnums;
import cc.rengu.igas.route.common.util.IPv4Util;
import cc.rengu.igas.route.core.helper.RouterHelper;
import cc.rengu.igas.route.core.model.CompleteRouteInfoBean;
import cc.rengu.igas.route.core.model.ProdInfoBean;
import cc.rengu.igas.route.core.model.RouterReq;
import cc.rengu.igas.route.core.realize.Router;
import cc.rengu.igas.route.core.realize.payment.DstChannelPaymentSignService;
import cc.rengu.igas.route.facade.request.IntelligencePaymentSignRequest;
import cc.rengu.igas.route.facade.response.IntelligencePaymentSignResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSONObject;

import java.util.List;

/**
 * 智能路由标准交易服务-对外付款签约
 *
 * @author xlz
 * @version 1.0
 * @date 20200423
 */
public class IntelligencePaymentSignService extends RadpService {
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            IntelligencePaymentSignRequest intelligencePaymentSignRequest = new IntelligencePaymentSignRequest();
            IntelligencePaymentSignResponse intelligencePaymentSignResponse;
            ConvertUtil.convertOutput(intelligencePaymentSignRequest);
            if (StringUtil.isEmptyOrNull(intelligencePaymentSignRequest.getFrontChannelId())) {
                rglog.error("必须上送前置渠道标志[frontChannelId]");
                throw new BizException(SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespCode(), SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespDesc());
            }

            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID, intelligencePaymentSignRequest.getHeader().getSrcSysId());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM, intelligencePaymentSignRequest.getHeader().getTraceNo());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_TIME, intelligencePaymentSignRequest.getHeader().getTransTime());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_DATE, intelligencePaymentSignRequest.getHeader().getTransDate());

            String sysSeqNum = null;
            //处理附加信息
            if (!StringUtil.isEmptyOrNull(intelligencePaymentSignRequest.getAdditionInfo())) {
                JSONObject jsonObject = JSONObject.parseObject(intelligencePaymentSignRequest.getAdditionInfo());
                jsonObject.forEach((key, value) -> {
                    try {
                        xmlTreeUtil.setXmlTreeStringValue(key, (String) value);
                    } catch (Exception e) {
                        rglog.error(e.getMessage());
                    }
                });
                sysSeqNum = (String) jsonObject.get(TreeNodeConstant.SYS_SEQ_NUM);
            }
            if (StringUtil.isEmptyOrNull(sysSeqNum)) {
                rglog.error("COPS未上送系统内部流水号");
                throw new BizException(SmartRouteRspEnums.TRANS_FAIL.getRespCode(), SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            }
            //根据通道标识,通道交易码确定通道服务类名
            String dstChannelId;
            String dstChannelTxnNum;
            String dstChannelTxnImplClassName;
            if (!StringUtil.isEmptyOrNull(intelligencePaymentSignRequest.getDstChannelId())) {
                dstChannelId = intelligencePaymentSignRequest.getDstChannelId();
                RouteTxnNumEnum routeTxnNumEnum = RouteTxnNumEnum.getInstance(intelligencePaymentSignRequest.getHeader().getTxnNum());
                if (null == routeTxnNumEnum) {
                    throw new BizException(SmartRouteRspEnums.NO_AUTH_ERROR.getRespCode(), SmartRouteRspEnums.NO_AUTH_ERROR.getRespDesc());
                }
                CompleteRouteInfoBean completeRouteInfoBean = RouterHelper.getCompleteRouteInfoBean(intelligencePaymentSignRequest.getHeader().getInstId(),
                        intelligencePaymentSignRequest.getHeader().getTxnNum(), routeTxnNumEnum.getTxnGroup(), dstChannelId, rglog);
                dstChannelTxnImplClassName = completeRouteInfoBean.getDstChannelTxnImplClassName();
                dstChannelTxnNum = completeRouteInfoBean.getDstTxnAuthCfg().getChannelTxn();
            } else {
                //调用智能路由获取最优通道
                RouterReq routerReq = new RouterReq();
                routerReq.setInstId(intelligencePaymentSignRequest.getHeader().getInstId());
                routerReq.setTransChanlId(intelligencePaymentSignRequest.getHeader().getChanlId());
                routerReq.setTxnGroup(RouteTxnNumEnum.PAYMENT.getTxnGroup());
                routerReq.setTransAmt(SmartRouteParamConstant.STRING_DEFAULT_ZERO);
                routerReq.setDelayedFlag("");
                routerReq.setBizCode(intelligencePaymentSignRequest.getBizCode());
                routerReq.setTxnNum(intelligencePaymentSignRequest.getHeader().getTxnNum());
                routerReq.setSrcSysId(intelligencePaymentSignRequest.getHeader().getSrcSysId());
                //付款方信息
                routerReq.setPayerInfo(intelligencePaymentSignRequest.getPayerInfo());
                //调用智能路由
                Router router = new Router();
                List<ProdInfoBean> listProdInfo = router.choice(routerReq);
                if (listProdInfo == null || listProdInfo.isEmpty()) {
                    rglog.error("调用智能路由未找到通道");
                    throw new BizException(SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespCode(), SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespDesc());
                }
                //默认取第一条优先级最高通道
                dstChannelId = listProdInfo.get(0).getDstChannelId();
                dstChannelTxnNum = listProdInfo.get(0).getDstChannelTxnNum();
                dstChannelTxnImplClassName = listProdInfo.get(0).getDstChannelTxnImplClassName();
            }

            //更新流水表dev_brand记录通道
            NonFinanceTxnRouteCustomMapper nonFinanceTxnMapper = new NonFinanceTxnRouteCustomMapperImpl();
            nonFinanceTxnMapper.updDevBrandByPriKey(intelligencePaymentSignRequest.getHeader().getInstId(), sysSeqNum, dstChannelId);

            //反射获取对应服务实例
            Class c = Class.forName(dstChannelTxnImplClassName);
            DstChannelPaymentSignService dstChannelPaymentSignService = (DstChannelPaymentSignService) c.newInstance();

            //通道压力+1
            boolean isIncrSucc = true;
            String keyStress = SmartRouteParamConstant.ROUTE_DATA_ALL_STRESS + ":" + AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
            try {
                RedisUtil.onceIncr(keyStress);
            } catch (Exception e) {
                rglog.warn(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                isIncrSucc = false;
            }
            //通道交易总笔数
            boolean isIncrSuccTotalCount = true;
            String keyTotalCount = SmartRouteParamConstant.ROUTE_DATA_ALL_TOTAL_COUNT + ":" + AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
            try {
                RedisUtil.onceIncr(keyTotalCount);
            } catch (Exception e) {
                rglog.warn(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                isIncrSuccTotalCount = false;
            }
            long channelStartTime = DateUtil.getCurrentTimeStamp();
            try {
                //调用对应通道交易
                intelligencePaymentSignResponse = dstChannelPaymentSignService.paymentSign(intelligencePaymentSignRequest);
            } finally {
                //调用通道的结束,设置通道耗时
                long channelEndTime = DateUtil.getCurrentTimeStamp();
                String timeCost = Long.valueOf(channelEndTime - channelStartTime).toString();
                String time13 = DateUtil.getCurrentDate() + DateUtil.getCurrentTime().substring(0, 5);
                String redisKey = AppParamConstant.DEFAULT_INSTID + ":" + dstChannelId;
                String nodeKey = redisKey + ":" + IPv4Util.ipv4Address;
                String transTimeKey = SmartRouteParamConstant.ROUTE_DATA_ALL_TIMECOST + ":" + redisKey + ":" + time13;
                String transTimeNodeKey = SmartRouteParamConstant.ROUTE_DATA_ALL_TIMECOST + ":" + nodeKey + ":" + time13;
                List<String> transTimeSplitList = RedisUtil.getListRange(transTimeKey, 0, 1);
                RedisUtil.onceRightPush(transTimeKey, timeCost);
                RedisUtil.onceRightPush(transTimeNodeKey, timeCost);
                if (null == transTimeSplitList || transTimeSplitList.isEmpty()) {
                    RedisUtil.onceExpire(transTimeKey, 300);
                    RedisUtil.onceExpire(transTimeNodeKey, 300);
                }
                //通道调用成功，redis计数器自减1(通道压力减少1)
                try {
                    if (isIncrSucc) {
                        RedisUtil.onceDecr(keyStress);
                    }
                } catch (Exception e) {
                    rglog.warn("通道<{}>压力统计redis计数器压力值-1异常{}", dstChannelId, cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                }
                //再次尝试总笔数+1
                try {
                    if (isIncrSuccTotalCount) {
                        RedisUtil.onceIncr(keyTotalCount);
                    }
                } catch (Exception e) {
                    rglog.warn("再次尝试通道<{}>交易总比数统计redis计数器+1异常{}", dstChannelId, cc.rengu.utility.base.StringUtil.ExceptionToString(e));
                }
            }

            //设置返回值
            intelligencePaymentSignResponse.setDstChannelId(dstChannelId);
            //默认短信验证
            intelligencePaymentSignResponse.setVerifyMode("01");
            //该交易为签约触发短信
            intelligencePaymentSignResponse.setSgnNo("");
            rglog.info("交易成功");
            ConvertUtil.convertInput(intelligencePaymentSignResponse);
        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(cc.rengu.utility.base.StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(cc.rengu.utility.base.StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_FAIL.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            } catch (Exception e1) {
                rglog.error(cc.rengu.utility.base.StringUtil.ExceptionToString(e1));
            }
        }
        return 0;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }
}
